/*
* Copyright (c) 2025 Shenzhen Kaihong Digital Industry Development Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const MAX_LABEL_LENGTH = 40;

class AttributeArea {
    constructor() {
        document.attrCallback = this;
        this.area = document.getElementById('attribute_area');
        this.htmlStr = '';

        this.callbackFuncs = {};
        this.searchId_ = 0;
    }
    nextSearchId() {
        this.searchId_++;
        return 'search_id_' + this.searchId_;
    }
    collectFuncs(options) {
        if (options.searchId === undefined) {
            options.searchId = this.nextSearchId();
        }
        if (options.callback !== undefined) {
            this.callbackFuncs[options.searchId] = options.callback;
        }
    }
    hide() {
        this.area.style.display = "none";
    }
    show() {
        this.area.style.display = "block";
    }
    clear() {
        this.htmlStr = '';
        this.callbackFuncs = {};
    }
    flush() {
        this.area.style.display = "block";
        this.area.innerHTML = this.htmlStr;
    }
    insertStyle(type = "unknow", options = {}) {
        let ret = ' style="';
        if (options.width) ret += `width: ${options.width};`;
        else ret += `width: ${420 - (10 + 3) * 2}px;`;

        if (options.center) {
            ret += 'display: flex;';
            ret += "align-items: center;";

        }
        ret += "align-items: center;";
        ret += "justify-content: center;"
        if (options.backgroundColor) ret += `background-color: ${options.backgroundColor};`;
        else ret += `background-color: #333333;`;
        if (options.borderRadius) ret += `border-radius: ${options.borderRadius};`;
        else ret += `border-radius: 5px;`;
        if (options.border) ret += `border: ${options.border} solid #555555;`;
        else ret += `border: 1px solid #555555;`;
        if (options.padding) ret += `padding: ${options.padding};`;
        else ret += `padding: 3px;`;
        if (options.marginL) {
            ret += `margin-left: ${options.marginL};`;
            ret += `margin-right: 0px;`;
        }
        else if (options.marginR) {
            ret += `margin-left: 0px;`;
            ret += `margin-right: ${options.marginR};`;
        }
        else if (options.marginLR) {
            ret += `margin-left: ${options.marginLR};`;
            ret += `margin-right: ${options.marginLR};`;
        }
        else {
            ret += `margin-left: 10px;`;
            ret += `margin-right: 10px;`;
        }
        if (options.marginUD) {
            ret += `margin-top: ${options.marginUD};`;
            ret += `margin-bottom: ${options.marginUD};`;
        }
        else {
            ret += `margin-top: 0px;`;
            ret += `margin-bottom: 0px;`;
        }
        if (options.color) ret += `color: ${options.color};`;
        else ret += `color: #ffffff;`;
        if (options.fontSize) ret += `font-size: ${options.fontSize};`;
        else ret += `font-size: 14px;`;
        if (options.height) ret += `height: ${options.height};`;
        else ret += `height: 32px;`;
        ret += 'text-decoration: none;';
        ret += 'cursor: pointer;';
        ret += 'list-style-type: none;';

        ret += '" ';
        return ret;
    }
    insertCallback(searchId, type, value, fname = 'onclick') {
        let ret = ` ${fname}="document.attrCallback.Event(`;
        ret += "this",
            ret += ",'" + searchId + "'";
        ret += ",'" + type + "'";
        ret += ",'" + value + "'";
        ret += ')" ';
        return ret;
    }
    addTitle(name) {
        let ret = '<div';
        ret += this.insertStyle("title", {
            width: '100%',
            height: '48px',
            fontSize: '18px',
            marginLR: '0px',
            padding: '0px',
            border: 'none',
            borderRadius: '0px',
            center: true,
        });
        ret += '>';
        ret += '<p>' + name + '</p>';
        ret += '</div>';
        this.htmlStr += ret;
    }
    addGap(count = 1) {
        for (let i = 0; i < count; i++) {
            this.htmlStr += '<br>';
        }
    }
    addLabel(options) {
        let ret = '<div><p';
        ret += this.insertStyle("label", {
            backgroundColor: 'none',
            height: 'none',
            border: 'none',
            borderRadius: '0px',
            fontSize: '16px',
        });
        if (options.title) {
            ret += ' title="' + options.title + '" ';
        }
        ret += '>';
        ret += options.label + '</p>';
        ret += '</div>';
        this.htmlStr += ret;
    }
    addInput(options) {
        this.collectFuncs(options);
        if (options.label) {
            this.addLabel(options);
        }
        let ret = '<input id="' + options.searchId + '"' + this.insertStyle("input", {
            marginLR: '32px',
            width: '80%',
            height: '24px',
        });
        ret += this.insertCallback(options.searchId, 'input', options.default, 'oninput');
        ret += ` value="${options.default}" `;
        ret += '></input><br>';
        this.htmlStr += ret;
    }
    addCheckbox(options) {
        this.collectFuncs(options);
        let ret = '<label' + this.insertStyle("checkbox", {
            border: 'none',
            borderRadius: '0px',
            marginLR: '32px',
            width: '80%',
            fontSize: '16px',
            backgroundColor: 'none',
        }) + '><input type="checkbox" id="' + options.searchId + '"';
        ret += this.insertCallback(options.searchId, 'checkbox', options.default, "onchange");
        if (options.default) ret += ` checked `;
        ret += '></input>' + options.label + '</label>';
        this.htmlStr += ret;
    }
    addButton(options) {
        this.collectFuncs(options);
        if (options.label.length > MAX_LABEL_LENGTH) {
            options.label = options.label.substring(0, MAX_LABEL_LENGTH) + '...';
        }
        let ret = '<button' + this.insertStyle("button", {
            backgroundColor: '#272727',
        });
        ret += this.insertCallback(options.searchId, 'button', options.label);
        ret += '>' + options.label + '</button><br>';
        this.htmlStr += ret;
    }
    addList(options) {
        this.collectFuncs(options);
        if (options.label) {
            this.addLabel(options);
        }
        let ret = '<ul id="' + options.searchId + '"' + this.insertStyle("list", {
            height: options.height ? options.height + "px; overflow-y: auto;" : 'none',
            marginLR: '32px',
            width: '80%',
        }) + '>';
        for (let i in options.list) {
            ret += '<li' + this.insertCallback(options.searchId, 'list', options.list[i]);
            if (options.default && options.default == options.list[i]) ret += ` style="background-color: #3498db;" `;
            ret += '>';
            ret += options.list[i];
            ret += '</li>';
        }
        ret += '</ul>';
        this.htmlStr += ret;
    }
    addDropdown(options) {
        this.collectFuncs(options);
        this.addLabel(options);
        let ret = '<select id="' + options.searchId + '"' + this.insertStyle("select", {
            marginLR: '32px',
            width: '80%',
        });
        ret += this.insertCallback(options.searchId, 'select', options.default, "onchange");
        ret += '>';
        for (let i in options.list) {
            ret += '<option value="' + options.list[i] + '"';
            if (options.default == options.list[i]) ret += ` selected `;
            ret += '>' + options.list[i] + '</option>';
        }
        ret += '</select>';
        this.htmlStr += ret;
    }
    addLabelInput(options) {
        this.collectFuncs(options);
        let ret = '<div style="display: flex;align-items: center; white-space: nowrap;"><p';
        // let ret = '<div style="display: grid; grid-template-columns: auto 1fr; gap: 10px; align-items: center;"><p';
        ret += this.insertStyle("label", {
            backgroundColor: 'none',
            width: 'none',
            height: 'none',
            marginL: '20px',
            border: 'none',
            borderRadius: '0px',
            fontSize: '14px',
            // width: '30%'
        });
        ret += '>';
        ret += options.label + '</p>';

        ret += '<input id="' + options.searchId + '"';
        ret += this.insertStyle("input", {
            marginR: '20px',
            width: options.width ? options.width : '50%',
            height: 'none',
        });
        ret += this.insertCallback(options.searchId, 'input', options.default, 'oninput');
        ret += ` value="${options.default}" `;
        ret += '></input></div>';
        this.htmlStr += ret;
    }
    addMultElements(optionLists) {//单行中包含多个元素
        let ret = '<div style="display: flex;align-items: center; white-space: nowrap;margin-left: 20px;margin-right: 20px;margin-top: 10px;margin-bottom: 10px">';
        for (let options of optionLists) {
            switch (options.type) {
                case 'button':
                    this.collectFuncs(options);
                    ret += '<button' + this.insertStyle("button", {
                        backgroundColor: '#272727',
                        width: 'none',
                        marginLR: '5px',
                    });
                    ret += this.insertCallback(options.searchId, 'button', options.label);
                    ret += '>' + options.label + '</button>';
                    break;
            }
        }
        ret += '</div>';
        this.htmlStr += ret;
    }
    addLabelInputs(optionLists) {
        let ret = '<div style="display: flex;align-items: center; white-space: nowrap;margin-left: 20px;margin-right: 20px;margin-top: 10px;margin-bottom: 10px">';
        for (let options of optionLists) {
            this.collectFuncs(options);
            ret += '<p';
            // let ret = '<div style="display: grid; grid-template-columns: auto 1fr; gap: 10px; align-items: center;"><p';
            ret += this.insertStyle("label", {
                backgroundColor: 'none',
                width: 'none',
                height: 'none',
                marginL: '5px',
                border: 'none',
                borderRadius: '0px',
                fontSize: '14px',
                // width: '30%'
            });
            ret += '>';
            ret += options.label + '</p>';

            ret += '<input id="' + options.searchId + '"';
            ret += this.insertStyle("input", {
                marginR: '5px',
                width: options.width ? options.width : '50%',
                height: 'none',
            });
            ret += this.insertCallback(options.searchId, 'input', options.default, 'oninput');
            ret += ` value="${options.default}" `;
            ret += '></input>';
        }
        ret += '</div>';
        this.htmlStr += ret;
    }
    addLabelDropdown(options) {
        this.collectFuncs(options);
        let ret = '<div style="display: flex;align-items: center; white-space: nowrap;"><p';
        // let ret = '<div style="display: grid; grid-template-columns: auto 1fr; gap: 10px; align-items: center;"><p';
        ret += this.insertStyle("label", {
            backgroundColor: 'none',
            width: 'none',
            height: 'none',
            marginL: '20px',
            border: 'none',
            borderRadius: '0px',
            fontSize: '14px',
            // width: '30%'
        });
        ret += '>';
        ret += options.label + '</p>';

        ret += '<select id="' + options.searchId + '"';
        ret += this.insertStyle("select", {
            marginR: '20px',
            width: '100%',
            height: 'none',
        });
        ret += this.insertCallback(options.searchId, 'select', options.default, 'onchange');
        ret += '>';
        for (let i in options.list) {
            ret += '<option value="' + options.list[i] + '"';
            if (options.default == options.list[i]) ret += ` selected `;
            ret += '>' + options.list[i] + '</option>';
        }
        ret += '</select></div>';
        this.htmlStr += ret;
    }
    updateSelect(searchId, selectList) {
        let e = document.getElementById(searchId);
        e.innerHTML = '';
        for (let i in selectList) {
            e.innerHTML += '<option value="' + selectList[i] + '">' + selectList[i] + '</option>';
        }
    }

    // addImage
    // addDotLine
    // addValidatorInput
    // addTextArea

    Event(self, searchId, type, value) {
        if (this.callbackFuncs[searchId] !== undefined) {
            if (type == "button") {
                this.callbackFuncs[searchId]();
            } else if (type == "input") {
                this.callbackFuncs[searchId](self.value);
            } else if (type === 'checkbox') {
                this.callbackFuncs[searchId](self.checked);
            } else if (type === 'select') {
                this.callbackFuncs[searchId](self.value);
            } else if (type === 'list') {
                let e = document.getElementById(searchId);
                for (let l of e.getElementsByTagName('li')) {//枚举列表中的选项
                    if (self == l) l.style.backgroundColor = '#3498db';
                    else l.style.backgroundColor = null;
                }
                this.callbackFuncs[searchId](value);
            }
        }
    }
}
AttributeArea.pInstance_ = null;
AttributeArea.gi = function () {
    if (AttributeArea.pInstance_ === null) {
        AttributeArea.pInstance_ = new AttributeArea();
    }
    return AttributeArea.pInstance_;
};

module.exports = {
    AttributeArea,
};
